/*******************************************************************************
 * Witz - Winboard Chess Engine                                                *
 * MAIN.C                                                                      *
 *                                                                             *
 * The main for the Witz Chess Engine.  This program is currently designed to  *
 * be a single threaded program.  Please see build.h for compile flags.        *
 *                                                                             *
 * This program is free software; you can redistribute it and/or modify        *
 * it under the terms of the GNU General Public License as published by        *
 * the Free Software Foundation; either version 2 of the License, or           *
 * (at your option) any later version.                                         *
 *                                                                             *
 * This program is distributed in the hope that it will be useful,             *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of              *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
 * GNU General Public License for more details.                                *
 *                                                                             *
 * You should have received a copy of the GNU General Public License           *
 * along with this program; if not, write to the Free Software                 *
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   *
 *                                                                             *
 * Copywright (C) 2006 Pradu Kannan                                            *
 * http://witz.sf.net/                                                         *
 ******************************************************************************/

#include "build.h"
#ifdef __WINDOWS__
	#include <windows.h>
#else
	#include <unistd.h>
	#include <sys/select.h>
#endif
#include <stdio.h>
#include <signal.h>
#include "defs.h"
#include "protos.h"
#include "threads.h"
#include "data.h"

char currentDir[1024];

bool	openedInConsole;
char*	dumpFileLocationPointer=NULL;

#ifdef __WINDOWS__
	HANDLE	hInput;
#endif

/*main()
 *starts the program off
 *@returns false if there was a successful operation
 */
void main(int argc, char *argv[])
{
	char input[256];
	int i;

	NO_PROCESSORS = getNoProcessors();
	
	//use unbuffered input and output
	setbuf(stdout, NULL);
	setbuf(stdin, NULL);
	//ingnore signals SIGINT and SIGTERM
	signal(SIGINT, SIG_IGN);
	signal(SIGTERM, SIG_IGN);
	//seed the library (not MT) random number generator
	srand((unsigned)time(NULL));

	//get the current directory
	for(i=(int)strlen(*argv)-1;i>=0;i--)
	{
		if((*argv)[i]=='\\' || (*argv)[i]=='/')
		{
			bool tempBool=false;
			char tempChar;
			if(i!=(int)strlen(*argv)-1)
			{
				tempBool=true;
				tempChar=(*argv)[i+1];
				(*argv)[i+1]='\0';
			}
			if(i>0)
				strcpy(currentDir,*argv);
			else
				*configPath='\0';
			if(tempBool)
				(*argv)[i+1]=tempChar;
			break;
		}
	}

	//handle command line parameters
	strcpy(configPath,currentDir);
	strcat(configPath,default_configPath);
	if(argc>1)
	{
		if(!strncmp(argv[1],"config",6))
		{
			printf("%s\n",argv[2]);
			if(argc>2)
				strcpy(configPath,argv[2]);
			else
				printf("Not enough parameters\n\n");
		}
		else if(!strncmp(argv[1],"makebook",8))
		{
			if(argc<5)
				printf("Not enough parameters");
			else
			{
				createBook(argc,argv);
				quit();
			}
		}
		else
		{
			if(strpbrk(argv[1],".wdmp")!=NULL)
			{
				printf("Witz %sCopyright (C) %s Pradu Kannan\n",PROGRAM_VERSION,COPYWRIGHT_YEAR);
				dumpFileLocationPointer=argv[1];
				openedInConsole=true;
				xboard();
				return;
			}
			else
				printf("Unknown command line option: %s\n----------\n",argv[1]);
		}
	}
	if(setOpenedInConsole())
	{
		printf("Witz %s\nCopyright (C) %s Pradu Kannan\n",PROGRAM_VERSION,COPYWRIGHT_YEAR);
		printLicenceStatement();
		printWinboardNotice();
		for(;;)
		{
			printPrompt();
			fflush(stdout);
			if(!fgets(input, 256, stdin))
				printf("FATAL ERROR!\n");
			if(!strcmp(input,"show w\n"))
				printShowW();
			else if(!strcmp(input,"show c\n"))
				printShowC();
			else if(!strcmp(input,"xboard\n"))
			{
				xboard();
				return;
			}
			else
				return;
		}
	}
	scanf("%s",input);
	if(!strcmp(input,"xboard"))
	{
		xboard();
		return;
	}
	return;
}

/*setOpenedInConsole()
 *determines whether the program was opened in a console
 *sets openedInConsole and hInput
 *
 *@returns true if it is opened in a console
 *Note: works only for Windows and Unix systems
 */
bool setOpenedInConsole()
{
#ifdef __WINDOWS__
	DWORD dwConsoleMode, dwAvailable;
	hInput = GetStdHandle(STD_INPUT_HANDLE);
	if(!GetConsoleMode(hInput,&dwConsoleMode))
     	return openedInConsole=PeekNamedPipe(hInput,0,0,0,&dwAvailable,0)==0;
	return openedInConsole=true;
#else
	return openedInConsole=isatty(fileno(stdin));
#endif
}

/*printLicenceStatement()
 *prints a licence statement
 */
void printLicenceStatement()
{
	puts("\nWitz comes with ABSOLUTELY NO WARRANTY; for details type `show w'.");
	puts("This is free software, and you are welcome to redistribute it");
	puts("under certain conditions; type `show c' for details.");
}

/*printWinboardNotice()
 *prints a winboard notice
 */
void printWinboardNotice()
{
	printf("\nType 'xboard' to use Witz in console, otherwise type anything else to exit.\n");
	printf("If you do not know xboard commands, you might want to download a winboard\n");
	printf("interface. A listing of some interfaces is at http://witz.sourceforge.net/.\n\n");
}

/*printShowW()
 *prints an excerpt from the GNU GPL about warranty
 */
void printShowW()
{
	puts("\nBECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY");
	puts("FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN");
	puts("OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES");
	puts("PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED");
	puts("OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF");
	puts("MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS");
	puts("TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE");
	puts("PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,");
	puts("REPAIR OR CORRECTION.\n");
}

/*printShowC()
 *prints an excerpt from the GNU GPL about redistribution
 */
void printShowC()
{
	puts("\nIN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING");
	puts("WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR");
	puts("REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,");
	puts("INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING");
	puts("OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED");
	puts("TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY");
	puts("YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER");
	puts("PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE");
	puts("POSSIBILITY OF SUCH DAMAGES.\n");
}

/*printPrompt()
 *prints the witz> prompt
 */
void printPrompt()
{
	printf("\nwitz>");
}

/*quit()
 *closes the engine
 */
void quit()
{
	if(TT!=NULL) free(TT);

	FreeQueue(&operationQueue);
	FreeQueue(&resultQueue);
	ReleaseThreads(NO_PROCESSORS);

	DeleteCriticalSection(&TTLock);
	exit(0);
}

int getNoProcessors()
{
	SYSTEM_INFO siSysInfo;
	GetSystemInfo (&siSysInfo);
	return siSysInfo.dwNumberOfProcessors;	
}